package com.doubi.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class CommonUtils {

    private static Logger logger = LoggerFactory.getLogger(CommonUtils.class);

    /**
     * 功能描述：正数转负数
     * @author   MrDoubi 2019-06-29 14:00
     * @param param     参数
     * @return          值
     */
    public static double plusToMinus(double param) {
        return 0 - param;
    }

    /** 
     * 功能描述：正数转负数
     * @author   MrDoubi 2019-06-29 14:00
     * @param param     参数
     * @return          值
     */
    public static BigDecimal plusToMinus(BigDecimal param) {
        return new BigDecimal(0).subtract(param);
    }

    /**
     * 功能描述：转换成BigDecimal对象
     * @author   MrDoubi 2019-06-29 14:01
     * @param value     参数
     * @return          值
     */
    public static BigDecimal getBigDecimal(Object value) {
        BigDecimal ret = null;
        if (value != null) {
            if (value instanceof BigDecimal) {
                ret = (BigDecimal) value;
            } else if (value instanceof String) {
                ret = new BigDecimal((String) value);
            } else if (value instanceof BigInteger) {
                ret = new BigDecimal((BigInteger) value);
            } else if (value instanceof Number) {
                ret = new BigDecimal(((Number) value).doubleValue());
            } else {
                throw new ClassCastException("Not possible to coerce [" + value + "] from class " + value.getClass() + " into a BigDecimal.");
            }
        }
        return ret;
    }

    /** 
     * 功能描述：获取对象中的属性,并组装为格式:A,B,C,D
     * @author   MrDoubi 2019-06-29 14:04
     * @param clz               对象的类class
     * @param list              对象数组
     * @param attributeName     对象的属性名称
     * @return                  值
     */
    public static String getAttributeValue(Class clz, List list, String attributeName) {
        StringBuilder result = new StringBuilder();
        String name = "";
        Method[] methods = clz.getMethods();
        Method method = null;
        for (Method value : methods) {
            name = value.getName().toUpperCase();
            if (name.startsWith("GET") && name.substring(3).equalsIgnoreCase(attributeName)) {
                method = value;
                break;
            }
        }
        Iterator it = list.iterator();
        try {
            while (it.hasNext()) {
                assert method != null;
                result.append(",").append(method.invoke(it.next()));
            }
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            e.printStackTrace();
        }
        if (DataUtil.isNotEmpty(result.toString())) {
            return result.substring(1);
        }
        return "";
    }

    /** 
     * 功能描述：从Map中取键为keyAttributeName的值，并确放入list的属性valueAttributeName中
     * @author   MrDoubi 2019-06-29 14:07
     * @param clz                   对象的类class
     * @param list                  对象数组
     * @param map                   键值对
     * @param keyAttributeName      属性，为Map中的键
     * @param valueAttributeName    属性，为list中的属性
     */
    public static void setAttributeValue(Class clz, List list, Map map, String keyAttributeName, String valueAttributeName) {
        String name = "";
        Method[] methods = clz.getMethods();
        Method getMethod = null;
        Method setMethod = null;
        for (Method method : methods) {
            name = method.getName().toUpperCase();
            if (name.startsWith("GET") && name.substring(3).equalsIgnoreCase(keyAttributeName)) {
                getMethod = method;
            } else if (name.startsWith("SET") && name.substring(3).equalsIgnoreCase(valueAttributeName)) {
                setMethod = method;
            }
        }
        Iterator it = list.iterator();
        try {
            Object obj = null;
            while (it.hasNext()) {
                obj = it.next();
                assert setMethod != null;
                assert getMethod != null;
                setMethod.invoke(obj, map.get(getMethod.invoke(obj)));
            }
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

}
